# coding:utf-8
import re

dic_sav_par = {}


def get_varparam(data, excel_param, response_result):
	"""
	获取key，然后变量路径查找相关的json路径获取到 val，最终放入字典
	:param excel_param: 需要获取excel中的某个列名
	:param data: excel中返回的 一行数据
	:param response_result: json返回的数据
	:return:  dict 类型
	excel中需要保存的变量格式为(需要将此格式解析)：
	第一种：    token=$.result.token, ,la=$.result.userhaha.phone[1]
	第二种：    code
	"""
	# 判断类型
	if isinstance(response_result, dict):
		vars_pa = data[excel_param]
		tmps = vars_pa.split(',')
		# 获取 excel中 将要保存的变量，将变量key 和value 拿到
		for tmp in tmps:
			key = tmp.split('=')[0]
			# 兼容变量路径只有一层的情况，比如 只需要获取 success 值
			if len(tmp.split('=')) == 1:
				ll = [key]
				# 传入的第一个参数需要 list，注意
				val = find_param(ll, response_result)
			else:
				val_tmp = tmp.split('=')[1].replace('$','').split('.')
				val_tmp2 = [x for x in val_tmp if x]
				val = find_param(val_tmp2, response_result)
			print("保存的接口参数： {0} : {1}".format(key, val))
			dic_sav_par[key] = val
	else:
		print("返回数据格式类型非字典！")
	return dic_sav_par


def get_varparam2(data, excel_param, response_result):
	"""
	仅用来获取 excel中 check_param 字段对应的值，因为此值不能用缓存，否则save_param 的上下文变量数据会有问题（因为两者变量格式一样）
	excel中需要获取校验字段的 变量格式为(需要将此格式解析)：
	第一种：    token=$.result.token,la=$.result.userhaha.phone[1]
	第二种：    code
	:param data: excel一行数据
	:param excel_param: excel 列名
	:param response_result: 接口请求的返回数据
	:return:  list类型，不采用字典类型，因为预期结果 和excel 预期字段 比对时，字典顺序是无序的
	"""
	list_check_par = []
	# 判断类型
	if excel_param != "check_param":
		assert False, "此方式只能用于获取 check_param 数据"
	if isinstance(response_result, dict):
		vars_pa = data[excel_param]
		tmps = vars_pa.split(',')
		# 获取 excel中 将要保存的变量，将变量key 和value 拿到
		for tmp in tmps:
			key = tmp.split('=')[0]
			# 兼容变量路径只有一层的情况，比如 只需要获取 success 值
			if len(tmp.split('=')) == 1:
				ll = [key]
				# 传入的第一个参数需要 list，注意
				val = find_param(ll, response_result)
			else:
				val_tmp = tmp.split('=')[1].replace('$','').split('.')
				val_tmp2 = [x for x in val_tmp if x]
				val = find_param(val_tmp2, response_result)
			print("{0} : {1}".format(key, val))
			list_check_par.append(val)
	else:
		print("返回数据格式类型非字典！")
	return list_check_par


def find_param(val_tmp2, response_result):
	"""
	迭代循环，获取最终的value值
	:param val_tmp2: 变量类型是 列表，  json的路径，也就是excel中需要获取的变量的路径
	:param response_result: 接口返回的json数据
	:return:
	"""
	for i in val_tmp2:
		while i in response_result:
			val_tmp2.remove(i)
			if len(val_tmp2) != 0:
				if isinstance(response_result[i], list) :
					# 拿列表首个元素，拆分其中的key 和 序号，以便确认list中第几个结构体中的参数值
					tmp = val_tmp2[0]
					# 拆分 key 和序号
					tmp2 = re.split('\W+', tmp)
					# 如果是有list，但是没有序号，默认取第一个结构体中的参数
					if len(tmp2) < 2:
						index = 0
					else:
						index = int(tmp2[1])
					# 更新列表中值，将原来的 “xxx[1]”去掉，插入“ xxx”到第一个
					key_i = tmp2[0]
					val_tmp2.pop(0)
					val_tmp2.insert(0, key_i)
					if len(val_tmp2) < 2:
						# 更新查找到的结构体, 查找到最后key只有一个了，直接获取key对应的值就行，不用再次循环
						response_result = response_result[i][index]
						return response_result[key_i]
					else:
						return find_param(val_tmp2, response_result[i][index])
				else:
					return find_param(val_tmp2, response_result[i])
			return response_result[i]
		print("在返回数据中找不到key对应的值")


def set_varparam(data_param, dic_tmp):
	"""
	excel 列中有需要替换变量的字段
	:param data_param: excel 某个列的数据中，有需要替换变量的地方，格式${xxx}
	:param dic_tmp: 已经从get_varparm 方法中获取并且取值到的 变量值， 字典类型
	:return: 替换好变量后的 数据
	"""
	pattern = r"\$\{(.*?)\}"
	s = re.findall(pattern, data_param)
	# 没有合适的变量需要替换，则直接返回
	if len(s) != 0:
		for tmp in s:
			if tmp in dic_tmp:
				data_result = re.sub(r'\$\{(%s)\}'%tmp, str(dic_tmp[tmp]), data_param, 1)
				data_param = data_result
	return data_param


def assert_varparam(data, response_result):
	"""
	断言判断
	:param data: excel的一行数据，取check_param 参数
	:param response_result: 接口请求后返回数据
	:return:
	"""
	list_check_param = get_varparam2(data, "check_param", response_result)
	exp_re = data["exp_result"]
	list_exp_re = exp_re.split(',')
	print("实际结果：->: {}".format(list_check_param))
	print("预期结果：->: {}".format(list_exp_re))
	for i in range(len(list_check_param)):
		# json转换成python类型后，bool类型会被自动转换掉,所以此处要转换成 小写 比较
		if isinstance(list_check_param[i], bool):
			res_text = str(list_check_param[i]).lower()
		else:
			res_text = str(list_check_param[i])
		assert res_text == str(list_exp_re[i]), "断言期望不符合, 实际： {0} 预期： {1}".format(res_text, list_exp_re[i])

	# TODO 后续想要补充可以修改
	# assertEqual(exp_re, res_text, "断言期望不符合")


if __name__ == "__main__":
	rep = {'code':1001,'message':'成功','result':{'token':'eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxZzA0c3kiLCJjcmVhdGVkIjoxNTg0MDExNjM2Nzk5LCJleHAiOjE1ODQ2MTY0MzZ9.BTIiYwuV_2p6NODEo1_7uJHyBKrjXf4KfIUD_yRu6ZTdMS_i_pUaoOkhjpBHo_UCjA-XTWTHV5BdIZgf6ovq0A','userInfo':{'userId':13560013,'uname':'周ww','unick':'15tsdf的发生额','phone':'1506666666','avatar':'https://cdn.wanwudezhi.com/mall-portal/image/MTU3OTA5MjA3NjU0MQ==.jpg','gender':1,'birthday':1239344827,'type':1,'city':'杭州','country':'中国','province':'浙江','unionId':'orfggggg','openId':'oDgfI5trtrtr3hsZrpk','lastLoginTime':1584055364,'lastLoginIp':'113.3.3.3','invitationCode':'13540013','shopId':114991,'upgradePlayerTime':1579083362,'status':1,'isAuctionStatus':False,'liveUserStatus':1,'level':4,'userPlayerLevel':4,'userLevel':0,'userLevelName':'V0,青铜','isTagInfo':None,'userBind':False,'customerServiceUserId':None,'isExistenceCustomerServiceUser':1,'isLoginCustomerServiceUser':1,'secKillStatus':2,'supplyStatus':None},"test":[{"wecmail":"12345","phone":"15066666663","unbind":111,"myinfo":[{"name":"yeyun1","nick":"yeyun11"},{"name":"test-env1","nick":"dev-env1"}]},{"wecmail":"54321","phone":"15066666664","unbind":222,"myinfo":[{"name":"yeyun2","nick":"yeyun22"},{"name":"test-env2","nick":"dev-env2"}]}],'haha':[{"phone":"1234"},{"phone":"4321"}],'wechatInfo':None,'phoneCodeRegister':0,'unbind':0,'longPhone':None,'isTagInfo':0},'redirect':None,'success':True,'busy':False}
	# var_pa = {'rowNum': 4, 'case_name': 'login2', 'host': 'https://api.www.com', 'api': '/module-user/api/v1/user/v2/loginByPhoneAndAuthCode', 'request_method': 'post', 'check_param': 'success', 'exp_result': 'true', 'url_params': '', 'request_headers': '', 'formData': '{"phone":"15068878830","authCode":"656565"}', 'save_param': 'token=$.result.token, userid=$.result.userInfo.userId, haha=$.result.userInfo.level,la=$.result.userhaha.phone[1]', 'sleep': '', '': '登录'}
	var_pa = {'rowNum': 4, 'case_name': 'login2', 'host': 'https://api.www.com', 'api': '/module-user/api/v1/user/v2/loginByPhoneAndAuthCode', 'request_method': 'post', 'check_param': 'success,unamehh=$.result.userInfo.uname', 'exp_result': 'true,周ww', 'url_params': '', 'request_headers': '', 'formData': '{"phone":"1506666666","authCode":"656565"}', 'save_param': 'code,haha=$.result.userInfo.level', 'sleep': '', '': '登录'}
	var_pa2= {'rowNum': 6, 'case_name': 'list_info2', 'host': 'https://www.baidu.com', 'api': '/api/content/web/app/v1/video/related/list${haha}', 'request_method': 'get', 'check_param': 'success', 'exp_result': 'true', 'url_params': 'pageIndex=${haha}&pageSize=20', 'request_headers': '{"Appversion":"2.5.1","Authority":"Wwdz ${token}"}', 'formData': '{"phone":${haha},"authCode":"656565"}', 'save_param': '', 'sleep': '', 'remark': '卡罗拉(固定先写死关联)'}
	hahha = ['result', 'token']
	dics = get_varparam(var_pa, "save_param", rep)
	liu = get_varparam2(var_pa, "check_param", rep)
	# h = find_param(hahha, rep)
	# print("4445555 " + "{}".format(h))
	s2 = "pageIndex=${haha}&pageSize=20"
	s3 = '{"phone":"${haha}","authCode":"${userid}"}'
	s4 = "pageIndex=1&pageSize=20"
	s5 = "/api/content/web/app/v1/video/related/list${haha}"
	# print(dics)
	print("-- {}".format(liu))
	# dics = {'userid': 13440013, 'haha': 4}
	#dd = set_varparam(s3, dics)
	# print(dd)
	assert_varparam(var_pa, rep)